package com.view.cn.mvprxjava.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.view.cn.mvprxjava.R;

import java.util.Calendar;

/**
 * 自定义钟表
 * <p>
 * http://www.jianshu.com/p/86e867b9bee8
 * <p>
 * Created by Zengxiaoping on 2016/12/12.
 */

public class WatchBoard extends View {

	private float mPadding;             //边距
	private float mTextSize;            //文字大小
	private float mHourPointWidth;      //时针宽度
	private float mMinutePointWidth;    //分针宽度
	private float mSecondPointWidth;    //秒针宽度
	private float mPointRadius;         //指针圆角
	private float mPointEndLength;      //指针末尾的长度

	private int mLengthLongLine;        //长线的长度
	private int mLengthShortLine;       //短线的长度
	private int mColorLongLine;         //长线的颜色
	private int mColorShortLine;        //短线的颜色
	private int mColorHourPoint;        //时针颜色
	private int mColorMinutePoint;      //分针颜色
	private int mColorSecondPoint;      //秒针颜色

	private Paint mPaint;

	public WatchBoard(Context context) {
		super(context);
	}

	public WatchBoard(Context context, AttributeSet attrs) {
		super(context, attrs);
		initStyleAttrs(attrs);          //初始化属性
		initPaint();                    //初始化画笔
	}

	private void initPaint() {
		mPaint = new Paint();
		mPaint.setAntiAlias(true);      //设置抗锯齿
		mPaint.setDither(true);         //设置防抖动
	}

	private void initStyleAttrs(AttributeSet attrs) {
		TypedArray array = null;
		try {
			array = getContext().obtainStyledAttributes(attrs, R.styleable.WatchBoard);
			mPadding = array.getDimension(R.styleable.WatchBoard_mPadding, 10);
			mTextSize = array.getDimension(R.styleable.WatchBoard_mTextSize, 20);
			mHourPointWidth = array.getDimension(R.styleable.WatchBoard_mHourPointWidth, 5);
			mMinutePointWidth = array.getDimension(R.styleable.WatchBoard_mMinutePointWidth, 4);
			mSecondPointWidth = array.getDimension(R.styleable.WatchBoard_mSecondPointWidth, 3);
			mPointRadius = array.getDimension(R.styleable.WatchBoard_mPointRadiu, 10);
			mPointEndLength = array.getDimension(R.styleable.WatchBoard_mPointEndLength, 10);
			mLengthLongLine = (int) array.getDimension(R.styleable.WatchBoard_mLengthLongLine, 40);
			mLengthShortLine = (int) array.getDimension(R.styleable.WatchBoard_mLengthShortLine, 30);
			mColorLongLine = array.getColor(R.styleable.WatchBoard_mColorLongLine, Color.argb(225, 0, 0, 0));
			mColorShortLine = array.getColor(R.styleable.WatchBoard_mColorShortLine, Color.argb(125, 0, 0, 0));
			mColorHourPoint = array.getColor(R.styleable.WatchBoard_mColorHourPoint, Color.BLACK);
			mColorMinutePoint = array.getColor(R.styleable.WatchBoard_mColorMinutePoint, Color.BLACK);
			mColorSecondPoint = array.getColor(R.styleable.WatchBoard_mColorSecondPoint, Color.RED);
		} catch (Exception e) {
			//异常，全部使用默认值
			mPadding = 10;
			mTextSize = 20;
			mHourPointWidth = 5;
			mMinutePointWidth = 4;
			mSecondPointWidth = 3;
			mPointRadius = 10;
			mPointEndLength = 10;
			mLengthLongLine = 40;
			mLengthShortLine = 30;
			mColorLongLine = Color.argb(225, 0, 0, 0);
			mColorShortLine = Color.argb(125, 0, 0, 0);
			mColorHourPoint = Color.BLACK;
			mColorMinutePoint = Color.BLACK;
			mColorSecondPoint = Color.RED;
		} finally {
			//回收
			if (array != null) {
				array.recycle();
			}
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthHeight = 1000;

		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);

		if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED || heightMeasureSpec == MeasureSpec.AT_MOST || heightMeasureSpec == MeasureSpec.UNSPECIFIED) {
			try {
				throw new NoDetermineSizeException("宽度高度至少有一个确定的值,不能同时为wrap_content");
			} catch (NoDetermineSizeException e) {
				e.printStackTrace();
			}
		} else { //至少有一个为确定值,要获取其中的最小值
			if (widthMode == MeasureSpec.EXACTLY) {
				widthHeight = Math.min(widthHeight, widthSize);
			}
			if (heightMode == MeasureSpec.EXACTLY) {
				widthHeight = Math.min(widthHeight, heightSize);
			}
		}
		setMeasuredDimension(widthHeight, widthHeight);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		mPointRadius = (Math.min(w, h) - 10) / 2;
		mPointEndLength = mPointRadius / 6;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		canvas.save();
		canvas.translate(getWidth() / 2, getHeight() / 2); //移动开始位置
		paintCircle(canvas);                               //绘制圆背景
		paintLine(canvas);                                 //绘制线
		paintPointer(canvas);                              //绘制指针
		canvas.restore();
		postInvalidateDelayed(1000);                       //刷新
	}

	private void paintCircle(Canvas canvas) {
		mPaint.setColor(Color.WHITE);
		mPaint.setStyle(Paint.Style.FILL);
		canvas.drawCircle(0, 0, mPointRadius, mPaint);
	}

	private void paintLine(Canvas canvas) {
		mPaint.setStrokeWidth(2);
		int lineLength = 0;
		for (int i = 0; i < 60; i++) {
			if (i % 5 == 0) {                              //整点
				mPaint.setStrokeWidth(2);                  //粗细
				mPaint.setColor(mColorLongLine);           //颜色
				lineLength = 40;

				//-----------------处理整点文字----------------------------------------------------------------------
				String text = i / 5 == 0 ? (12 + "") : (i / 5 + "");
				Rect textRect = new Rect();
				mPaint.setTextSize(mTextSize);             //设置文字大小
				mPaint.getTextBounds(text, 0, text.length(), textRect);
				mPaint.setColor(Color.BLACK);              //设置文字颜色
				int textHeight = Math.abs(textRect.bottom - textRect.top);
				float textLocationY = -mPointRadius + mPadding + lineLength + 2 + textHeight;    //设置文字Y的坐标
				canvas.save();
				canvas.translate(0, textLocationY);
				canvas.rotate(-6 * i);
				mPaint.setStyle(Paint.Style.FILL);
				canvas.drawText(text, -(textRect.right - textRect.left) / 2, textRect.bottom + 5, mPaint);
				canvas.restore();
				//-----------------处理整点文字----------------------------------------------------------------------
			} else {
				mPaint.setStrokeWidth(1);
				mPaint.setColor(mColorShortLine);
				lineLength = 30;
			}
			canvas.drawLine(0, -mPointRadius + mPadding, 0, -mPointRadius + mPadding + lineLength, mPaint);
			canvas.rotate(6);                              //旋转6度
		}
	}

	private void paintPointer(Canvas canvas) {
		//时间
		Calendar calendar = Calendar.getInstance();
		int hour = calendar.get(Calendar.HOUR_OF_DAY);     //时
		int minute = calendar.get(Calendar.MINUTE);        //分
		int second = calendar.get(Calendar.SECOND);        //秒
		int angelHour = (hour % 12) * 360 / 12;            //时（角度）
		int angelMinute = minute * 360 / 60;               //分（角度）
		int angelSecond = second * 360 / 60;               //秒（角度）

		//画时钟
		canvas.save();
		canvas.rotate(angelHour);
		RectF rectHour = new RectF((int) (-mHourPointWidth / 2), (int) (-mPointRadius * (3.0 / 5.0)),
				(int) (mHourPointWidth / 2), (int) (mPointEndLength));
		mPaint.setColor(mColorHourPoint);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(mHourPointWidth);
		canvas.drawRoundRect(rectHour, mPointRadius, mPointRadius, mPaint);
		canvas.restore();
		//画分钟
		canvas.save();
		canvas.rotate(angelMinute);
		RectF rectMinute = new RectF((int) (-mMinutePointWidth / 2), (int) (-mPointRadius * (4.0 / 5.0)),
				(int) (mMinutePointWidth / 2), (int) (mPointEndLength));
		mPaint.setColor(mColorMinutePoint);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(mMinutePointWidth);
		canvas.drawRoundRect(rectMinute, mPointRadius, mPointRadius, mPaint);
		canvas.restore();
		//画秒钟
		canvas.save();
		canvas.rotate(angelSecond);
		RectF rectSecond = new RectF((int) (-mSecondPointWidth / 2), (int) (-mPointRadius + mPadding),
				(int) (mSecondPointWidth / 2), (int) (mPointEndLength));
		mPaint.setColor(mColorSecondPoint);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(mSecondPointWidth);
		canvas.drawRoundRect(rectSecond, mPointRadius, mPointRadius, mPaint);
		canvas.restore();
		//绘制中心小圆
		mPaint.setStyle(Paint.Style.FILL);
		mPaint.setColor(mColorSecondPoint);
		canvas.drawCircle(0, 0, mSecondPointWidth * 4, mPaint);
	}

	class NoDetermineSizeException extends Exception {
		public NoDetermineSizeException(String message) {
			super(message);
		}
	}

}
